﻿using Admin.Application.Const;
using Admin.Application.DynamicApi.System.Auth;
using Admin.Application.DynamicApi.System.Org;
using Admin.Application.DynamicApi.System.User.Dto;
using Admin.Database;
using Admin.Database.Enums;
using Admin.Database.Model;
using Framework.Core;
using Framework.Core.CustomException;
using Framework.DynamicApiController;
using Framework.SqlSugar;
using Framework.SqlSugar.Repository;
using Framework.Util.Encryption;
using Lazy.Captcha.Core;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Admin.Application.DynamicApi.System.User
{
	/// <summary>
	/// 用户服务 🧩
	/// </summary>
	[Service]
	public class SysUserService
	{
		private readonly SqlSugarRepository<SysUser> _sysUserRep;
		private readonly UserManager _userManager;
		private readonly SysOrgService _sysOrgService;
		private readonly ILogger<SysUserService> _logger;
		private readonly SysUserRoleService _sysUserRoleService;
		private readonly SysUserExtOrgService _sysUserExtOrgService;

		public SysUserService(ILogger<SysUserService> logger,
			SqlSugarRepository<SysUser> sysUserRep,
			SysOrgService sysOrgService,
			UserManager userManager,
			SysUserRoleService sysUserRoleService,
			SysUserExtOrgService sysUserExtOrgService
			)
		{
			_sysUserRep = sysUserRep;
			_sysOrgService = sysOrgService;
			_logger = logger;
			_userManager = userManager;
			_sysUserRoleService = sysUserRoleService;
            _sysUserExtOrgService = sysUserExtOrgService;
		}

		/// <summary>
		/// 获取用户分页列表 🔖
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[DisplayName("获取用户分页列表")]
		[AllowAnonymous]
		public async Task<SqlSugarPagedList<UserOutput>> page(PageUserInput input)
		{
			//获取子节点Id集合(包含自己)
			var orgList = await _sysOrgService.GetChildIdListWithSelfById(input.OrgId);

			return await _sysUserRep.AsQueryable()
				.LeftJoin<SysOrg>((u, a) => u.OrgId == a.Id)
				.Where(u => u.Account != "superadmin")
				.WhereIF(input.OrgId > 0, u => orgList.Contains(u.OrgId))
				.WhereIF(!string.IsNullOrWhiteSpace(input.Account), u => u.Account.Contains(input.Account))
				.WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name))
				.OrderBy(u => new { u.OrderNo, u.Id })
				.Select((u, a) => new UserOutput
				{
					OrgName = a.Name
				}, true)
				.ToPagedListAsync(input.Page, input.PageSize);
		}

		/// <summary>
		/// 增加用户 🔖
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[UnitOfWork]
		[HttpPost]
		[DisplayName("增加用户")]
		public virtual async Task<long> AddUser(AddUserInput input)
		{
			var isExist = await _sysUserRep.AsQueryable().ClearFilter().AnyAsync(u => u.Account == input.Account);
			if (isExist) throw new CustomException("账号已存在");

			//// 禁止越权新增超级管理员和系统管理员
			//if (_userManager.SuperAdmin) throw new CustomException("禁止越权操作系统账户");

			var password = MD5Encryption.Encrypt("111111", true, false);

			var user = input.Adapt<SysUser>();
			user.Password = password;
			var newUser = await _sysUserRep.AsInsertable(user).ExecuteReturnEntityAsync();

			input.Id = newUser.Id;
			await UpdateRoleAndExtOrg(input);

			return newUser.Id;
		}

		/// <summary>
		/// 更新用户 🔖
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[UnitOfWork]
		[HttpPost]
		[DisplayName("更新用户")]
		public virtual async Task UpdateUser(UpdateUserInput input)
		{
			if (await _sysUserRep.AsQueryable().ClearFilter().AnyAsync(u => u.Account == input.Account && u.Id != input.Id))
				throw new CustomException("账号已存在");

			//// 禁止越权新增超级管理员和系统管理员
			//if (_userManager.SuperAdmin) throw new CustomException("禁止越权操作系统账户");

			await _sysUserRep.AsUpdateable(input.Adapt<SysUser>()).IgnoreColumns(true)
				.IgnoreColumns(u => new { u.Password, u.Status }).ExecuteCommandAsync();

			await UpdateRoleAndExtOrg(input);

			// 删除用户机构缓存
			SqlSugarFilter.DeleteUserOrgCache(input.Id, _sysUserRep.Context.CurrentConnectionConfig.ConfigId.ToString());

			// 若账号的角色和组织架构发生变化,则强制下线账号进行权限更新
			//var user = await _sysUserRep.AsQueryable().ClearFilter().FirstAsync(u => u.Id == input.Id);
			//var roleIds = await GetOwnRoleList(input.Id);
			//if (input.OrgId != user.OrgId || !input.RoleIdList.OrderBy(u => u).SequenceEqual(roleIds.OrderBy(u => u)))
			//	await _sysOnlineUserService.ForceOffline(input.Id);

			//// 发布系统用户操作事件
			//await _eventPublisher.PublishAsync(SysUserEventTypeEnum.Update, new
			//{
			//	Entity = user,
			//	Input = input
			//});
		}

		/// <summary>
		/// 更新角色和扩展机构
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		private async Task UpdateRoleAndExtOrg(AddUserInput input)
		{
			await GrantRole(new UserRoleInput { UserId = input.Id, RoleIdList = input.RoleIdList });

			await _sysUserExtOrgService.UpdateUserExtOrg(input.Id, input.ExtOrgIdList);
		}

		/// <summary>
		/// 验证用户Id是否相同，若用户Id相同则报错
		/// </summary>
		/// <param name="userId">用户Id</param>
		/// <param name="errorMsg">自定义错误消息</param>
		public void ValidateIsUserId(SysUser user,long userId)
		{
			if (user.Id == userId)
			{
				throw new CustomException("非法操作，禁止删除自己");
			}
		}

		/// <summary>
		/// 删除用户 🔖
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[UnitOfWork]
		[HttpPost]
		[DisplayName("删除用户")]
		public virtual async Task DeleteUser(DeleteUserInput input)
		{
			var user = await _sysUserRep.GetByIdAsync(input.Id) ?? throw new CustomException("账号不存在");
			if (user.Account == "superadmin") throw new CustomException("禁止删除超级管理员");
			ValidateIsUserId(user,_userManager.UserId);

			await _sysUserRep.DeleteAsync(user);

			// 删除用户角色
			await _sysUserRoleService.DeleteUserRoleByUserId(input.Id);

			// 删除用户扩展机构
			await _sysUserExtOrgService.DeleteUserExtOrgByUserId(input.Id);

			//// 删除用户收藏菜单
			//await _sysUserMenuService.DeleteUserMenuList(input.Id);

			//// 发布系统用户操作事件
			//await _eventPublisher.PublishAsync(SysUserEventTypeEnum.Delete, new
			//{
			//	Entity = user,
			//	Input = input
			//});
		}

		/// <summary>
		/// 查看用户基本信息 🔖
		/// </summary>
		/// <returns></returns>
		[DisplayName("查看用户基本信息")]
		public virtual async Task<SysUser> GetBaseInfo()
		{
			return await _sysUserRep.GetByIdAsync(_userManager.UserId);
		}

		/// <summary>
		/// 更新用户基本信息 🔖
		/// </summary>
		/// <returns></returns>
		[HttpPost]
		[DisplayName("更新用户基本信息")]
		public virtual async Task<int> UpdateBaseInfo(SysUser user)
		{
			return await _sysUserRep.AsUpdateable(user)
				.IgnoreColumns(u => new { u.CreateTime, u.Account, u.Password,  u.OrgId }).ExecuteCommandAsync();
		}

		/// <summary>
		/// 设置用户状态 🔖
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[UnitOfWork]
		[DisplayName("设置用户状态")]
		public virtual async Task<int> SetStatus(UserInput input)
		{
			if (_userManager.UserId == input.Id)
				throw new CustomException("禁止修改本人账号状态");

			var user = await _sysUserRep.GetByIdAsync(input.Id) ?? throw new CustomException("账号不存在");
			if (user.Account == "superadmin") throw new CustomException("禁止修改超级管理员状态");
			if (!Enum.IsDefined(typeof(StatusEnum), input.Status))
				throw new CustomException("字典状态错误");

			user.Status = input.Status;
			var rows = await _sysUserRep.AsUpdateable(user).UpdateColumns(u => new { u.Status }).ExecuteCommandAsync();

			// 发布系统用户操作事件
			//if (rows > 0)
			//	await _eventPublisher.PublishAsync(SysUserEventTypeEnum.SetStatus, new
			//	{
			//		Entity = user,
			//		Input = input
			//	});

			return rows;
		}

		/// <summary>
		/// 授权用户角色 🔖
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[UnitOfWork]
		[DisplayName(displayName: "授权用户角色")]
		public async Task GrantRole(UserRoleInput input)
		{
			await _sysUserRoleService.GrantUserRole(input);

			//// 发布系统用户操作事件
			//await _eventPublisher.PublishAsync(SysUserEventTypeEnum.UpdateRole, input);
		}

		/// <summary>
		/// 修改用户密码 🔖
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[DisplayName("修改用户密码")]
		public virtual async Task<int> ChangePwd(ChangePwdInput input)
		{
			
			var user = await _sysUserRep.GetByIdAsync(_userManager.UserId) ?? throw new CustomException("账号不存在");
			if (user.Password != MD5Encryption.Encrypt(input.PasswordOld, true, false))
				throw new CustomException("旧密码输入错误");

			if (input.PasswordOld == input.PasswordNew)
				throw new CustomException("新密码不能与旧密码相同");

			user.Password = MD5Encryption.Encrypt(input.PasswordNew, true, false);

			var rows = await _sysUserRep.AsUpdateable(user).UpdateColumns(u => u.Password).ExecuteCommandAsync();

			// 发布系统用户操作事件
			//if (rows > 0)
			//	await _eventPublisher.PublishAsync(SysUserEventTypeEnum.ChangePwd, new
			//	{
			//		Entity = user,
			//		Input = input
			//	});

			return rows;
		}

		/// <summary>
		/// 重置用户密码 🔖
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[DisplayName("重置用户密码")]
		public virtual async Task<string> ResetPwd(ResetPwdUserInput input)
		{
			var user = await _sysUserRep.GetByIdAsync(input.Id) ?? throw new CustomException("账号不存在");
			user.Password = MD5Encryption.Encrypt("111111", true, false);
			await _sysUserRep.AsUpdateable(user).UpdateColumns(u => u.Password).ExecuteCommandAsync();

			//// 清空密码错误次数
			//var keyErrorPasswordCount = $"{CacheConst.KeyPasswordErrorTimes}{user.Account}";
			//_sysCacheService.Remove(keyErrorPasswordCount);

			//// 发布系统用户操作事件
			//await _eventPublisher.PublishAsync(SysUserEventTypeEnum.ResetPwd, new
			//{
			//	Entity = user,
			//	Input = input
			//});

			return "111111";
		}

		/// <summary>
		/// 获取用户拥有角色集合 🔖
		/// </summary>
		/// <param name="userId"></param>
		/// <returns></returns>
		[DisplayName("获取用户拥有角色集合")]
		public async Task<List<long>> GetOwnRoleList(long userId)
		{
			return await _sysUserRoleService.GetUserRoleIdList(userId);
		}

		/// <summary>
		/// 获取用户扩展机构集合 🔖
		/// </summary>
		/// <param name="userId"></param>
		/// <returns></returns>
		[DisplayName("获取用户扩展机构集合")]
		public async Task<List<SysUserExtOrg>> GetOwnExtOrgList(long userId)
		{
			return await _sysUserExtOrgService.GetUserExtOrgList(userId);
		}
	}
}
